#pragma once
#include "udpServer.hpp"
#include <vector>
#include <algorithm>
class MessageRounter
{

public:
    MessageRounter()
    {
        pthread_mutex_init(&_mutex,nullptr);
    }

    void addUser(const AddrInt& user)
    {
        //加锁
        pthread_mutex_lock(&_mutex);
        //检查用户是否存在
        auto item = std::find(_sockAddrs.begin(),_sockAddrs.end(),user);
        if(item != _sockAddrs.end())
        {
            pthread_mutex_unlock(&_mutex);
            return;
        }

        _sockAddrs.push_back(user);
        pthread_mutex_unlock(&_mutex);
    }

    void deleUser(const AddrInt& user)
    {
        pthread_mutex_lock(&_mutex);
        auto item = std::find(_sockAddrs.begin(),_sockAddrs.end(),user);
        if(item == _sockAddrs.end())
        {
            pthread_mutex_unlock(&_mutex);
            return;
        }

        _sockAddrs.erase(item);
        pthread_mutex_unlock(&_mutex);
    }

    static void* handlerTask(void* arg)
    {
        sendMessage* send = (sendMessage*)arg;

        //ip+端口号
        std::string msg = "[" + send->_addr.ip()+"/"+std::to_string(send->_addr.port()) +"]"+send->_message;
        std::cout<<"sendting..."<<msg<<std::endl;
        pthread_mutex_lock(&send->_self->_mutex);
        //开始转发
        for(auto& item:send->_self->_sockAddrs)
        {
            struct sockaddr_in cliaddr = item.addrin();
            sendto(send->_sockfd,
            send->_message.c_str(),
            sizeof(send->_message.c_str()),
            0,
            (struct sockaddr*)&cliaddr,
            sizeof(cliaddr));
        }

        pthread_mutex_unlock(&send->_self->_mutex);


        delete send;
        return nullptr;
    }

    void rounter(int sockfd,std::string message,AddrInt user)
    {
        addUser(user);
        if(message=="exit")
        {
            deleUser(user);
            return;
        }

        sendMessage* send = new sendMessage(this,sockfd,message,user);
        pthread_t tid;
        pthread_create(&tid,nullptr,handlerTask,send);
        pthread_detach(tid);
    }

    struct sendMessage
    {
        sendMessage(MessageRounter*self,int sockfd,std::string message,AddrInt addr)
        :_self(self)
        ,_sockfd(sockfd)
        ,_message(message)
        ,_addr(addr)
        {}
        MessageRounter* _self;
        int _sockfd;
        std::string _message;
        AddrInt _addr;
    };

    ~MessageRounter()
    {
        pthread_mutex_destroy(&_mutex);
    }

private:
    std::vector<AddrInt> _sockAddrs;
    pthread_mutex_t _mutex;
};